home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
dev
/
debug
/
sushi37_7.lzh
/
sushi.doc
< prev
Wrap
Text File
|
1993-02-23
|
12KB
|
393 lines
sushi v37.7
Copyright (c) 1992 Commodore-Amiga, Inc. All Rights Reserved
Sushi - intercepts raw serial debugging output on your own machine
startup options: [ON] [BUFK=n (power of 2 only)] [NOPROMPT] [QUIET] [ASKSAVE]
runtime options: [OFF] [SAVE] [SAVEAS filename] [EMPTY]
by Carolyn Scheppner - CATS
Thanks to Steve Tibbett and Christian E. Hopps for their own
implementations, "Reporter" and "Detective", which made me insatiably
curious and drove me to write my own.
Sushi is a tool to intercept the raw serial output of Enforcer 2.8b,
Enforcer.megastack 26.f, Mungwall, and all tool and application debugging
output that uses kprintf. This makes it possible to use serial debugging
on a single Amiga, without interfering with attached serial hardware
such as modems and serial printers. Sushi also provides optional
signalling and buffer access to an external display/watcher program.
QUICK USAGE
===========
Here's what's in my user-startup:
run >NIL: mungwall NAMETAG
; NOTE - with upcoming Enforcer 37.x, instead use: run >NIL: ENFORCER RAWIO
enforcer >NIL:
run >NIL: sushi <>"CON:0/20/640/100/Sushi CTRL-E=Empty CTRL-F=File/AUTO/CLOSE/WAIT/INACTIVE" ON BUFK=64 NOPROMPT
If Sushi can find Enforcer 2.8b, or 2.6f megastack resident, then it
can patch these Enforcers to redirect their output. Other debugging
output is intercepted by patching low level debugging output functions.
Upcoming versions of Enforcer (37.x) can not be found and patched in the
same way by Sushi (they have no port) - howvever, if you use the RAWIO
option of new 37.x Enforcer versions, Sushi will catch their output.
All standard serial debugging functions are intercepted. Currently,
the patch to the serial debugging input function just returns a 'y'.
Standard serial debugging output and Enforver output go into sushi's
circular buffer (user-definable size, default 32K), where it is noticed
by the Sushi process and written to stdout. The Sushi process is signalled
whenever a carriage return or linefeed comes through kprintf.
if Enforcer 2.8b or 2.6f has been found and patched, Sushi will also
wake up every 1/10 second to check for output in its buffer (since it
is not safe for Sushi's Enforcer wedge to signal Sushi's process during
an Enforcer bus error). If you are not using Enforcer 2.8b or 2.6f but
you still want Sushi to wake up every 1/10 second to check for output
(instead of only waking up on carriage returns and linefeeds), then pass
the special hidden command line option "TimerOn" when you start up Sushi.
Sushi's standard output can be redirected elsewhere (for example, to
a multiserial handler or an AUTO/WAIT/CLOSE CON window). Or Sushi can
be run in QUIET mode and external watcher/display tool can be signalled
by Sushi for more elaborate display of the output. (i.e. If you personally
want your machine to MOO when you get a mungwall hit, and flash purple
polka dots for Enforcer hits, you can write an external sushi watcher
or display tool to do that).
Sushi has several startup options, and several runtime options:
startup options: [ON] [BUFK=n (power of 2 only)] [NOPROMPT] [QUIET] [ASKSAVE]
[TIMERON]
runtime options: [OFF] [SAVE] [SAVEAS filename] [EMPTY]
Startup Options
===============
ON Default (not required)
BUFK=n Changes circular buffer size from default 32K to specified
power-of-2 K from 4K to 2028K. Sushi will always round
the specified size down to a power of two K (32K, 64K, etc).
NOPROMPT Turns off the "sushi installed" and "enforcer not found"
prompts. Useful if redirecting sushi to an AUTO CON
window in your user-startup.
QUIET Causes Sushi to just buffer all debugging output.
Effectively silences serial debugging output.
Useful in conjunction with an external sushi watcher
or displayer (see later explanation).
ASKSAVE Cause Sushi to ask you if you want to save the buffer
when you exit Sushi. If there's nothing in the buffer,
it won't ask. Make SURE sushi has a stdin if you
use this option. If sushi thinks it has no stdin,
it will save to t:sushi.out.
TIMERON Cause Sushi to wake up every 1/10 second to check for
output even if Enforcer 2.8b or 2.6f have not been patched.
Without this option, Sushi will just wake up every time a
carriage return or linefeed is output.
Runtime Options
===============
OFF Signals active running copy of Sushi to exit (CTRL_C)
EMPTY Signals active running copy of Sushi to empty its buffer.
SAVE Finds active running copy of Sushi and saves its buffer
as t:sushi.out
SAVEAS name Finds active running copy of Sushi and saves its buffer
as specified filename
Example Startup Usage
=====================
sushi ASKSAVE (in its own shell window)
run >NIL: sushi >"CON:0/20/640/120/Sushi/AUTO/CLOSE/WAIT" ON NOPROMPT INACTIVE
run >NIL: sushi <>"CON:0/20/640/120/Sushi/AUTO/CLOSE/WAIT" ON NOPROMPT INACTIVE
NOTE !!! The double redirection as above (<>) works with Amiga CON:
V37 or higher. It may not work with some third-party CON's.
The ASKSAVE option requires input from the CON window.
run sushi >ram:hits (all output redirected to a file)
run sushi NOPROMPT QUIET (for use with external displayer)
NOTE: You may want use the following title for a sushi AUTO CON window:
/Sushi CTRL-E:Empty CTRL-F:File/
Keyboard and BREAK signals
==========================
CTRL-C: To quit Sushi, CTRL-C it (if it has its own window), send it
a CTRL-C with the c:BREAK command, or run sushi a second time
with the OFF keyword.
CTRL-E: Tells Sushi to empty (clear) its buffer.
CTRL-F: Tells Sushi to save its own buffer to file t:sushi.out
Other Runtime Usage
===================
sushi OFF ; tell active running Sushi to try to exit
sushi SAVE ; save buffer of active Sushi
sushi SAVEAS ram:myhits EMPTY ; save buffer as ram:myhits and clear buffer
Usually, I just CTRL-F in the Sushi window, and it saves its buffer as
t:sushi.out.
Programmer Interface
====================
Sushi allows a external tasks to find and read its buffer, and allows
one external task to register itself to be signalled by Sushi
whenever there is new information in the buffer. Sushi will refuse
to exit as long as a task is registered with it. So make sure
you remove your pointer from Sushi's port before you exit !!!!
Here is an example that finds Sushi and installs itself as the
external sigtask. Sushi will signal this task whenever there
is new information in sushi's buffer.
The example also shows (ifdef'd out) how to ask Sushi to
write its buffer, flush its buffer, or exit.
;/* ext_sushi.c - Execute me to compile me with SAS C 5.10
LC -b1 -cfistq -v -y -j73 ext_sushi.c
Blink FROM LIB:c.o,ext_sushi.o TO ext_sushi LIBRARY LIB:LC.lib,LIB:Amiga.lib
quit
ext_sushi.c - An example of an external display or watcher program
which is signalled by sushi.
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef LATTICE
int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
void chkabort(void) { return; } /* really */
extern struct Library *SysBase;
extern struct Library *DOSBase;
#include "pragmas/exec_pragmas.h"
#include "pragmas/dos_pragmas.h"
#endif
#define MINARGS 1
UBYTE *vers = "\0$VER: ext_sushi 37.2";
UBYTE *Copyright =
"ext_sushi v37.2\nCopyright (c) 1992 Commodore-Amiga, Inc. All Rights Reserved";
UBYTE *usage = "Usage: ext_sushi";
void bye(UBYTE *s, int e);
void cleanup(void);
UBYTE sushiname[] = "sushi_CAS_port";
/* Definitions of WTP and AppStruct structures */
struct AppStruct {
/* These are for READ-ONLY use by external application */
UBYTE *subuf; /* Sushi's circular output buffer */
ULONG subufsize; /* Size of buffer in bytes (a power of 2K) */
ULONG subufi; /* Where Sushi will place next char received */
ULONG subufli; /* Sushi's local index of what it has processed */
ULONG wrapcnt; /* How may times circular buffer has wrapped */
ULONG wrapmask; /* Hex mask Sushi uses when wrapping subufi */
/* External app writes to these if not in use; must clear them before exiting */
struct Task *extsigtask;
LONG extsignum;
ULONG extsignal;
/* Microseconds that Sushi waits between checking for Enforcer hits.
* Default is 100000 (1/10 sec). If you find it necessary to touch this,
* BE REASONABLE - and PUT BACK THE DEFAULT before you exit !!!!
* Note that Sushi itself is Signalled for all other debugging output
* any time a CR or LF is placed in buffer. Sushi will only signal
* the external task if there is actually something in the buffer.
*/
ULONG sumicros;
/* private stuff here - subject to moving since any additional
* public things will be added right here.
*/
};
/* Sushi's public named port - contains pointer to AppStruct above */
struct WTP {
struct MsgPort wtPort;
struct AppStruct *appstruct;
/* private stuff here - subject to moving since any additional
* public things will be added right here.
*/
};
struct WTP *wtp = NULL;
struct AppStruct *aps = NULL;
LONG sushisignum = -1;
BOOL GotSushi = FALSE;
void main(int argc, char **argv)
{
struct Task *mytask;
UBYTE *buf;
ULONG sushisignal, signals, bufi, bufli;
BOOL Done;
if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?'))
{
printf("%s\n%s\n",Copyright,usage);
bye("",RETURN_OK);
}
bufli = 0; /* this application's last index into sushi buffer */
mytask = FindTask(NULL);
GotSushi = FALSE;
Forbid();
if (wtp = FindPort(sushiname))
{
aps = wtp->appstruct;
if(! aps->extsigtask) /* You MUST not install if someone else has */
{
if((sushisignum = AllocSignal(-1)) != -1)
{
sushisignal = 1L << sushisignum;
aps->extsigtask = mytask;
aps->extsignum = sushisignum;
aps->extsignal = sushisignal;
buf = aps->subuf;
GotSushi = TRUE;
}
}
}
Permit();
if(!GotSushi)
bye("Can't allocate sushi - not found or in use\n", RETURN_FAIL);
Done = FALSE;
while(!Done)
{
signals = Wait( SIGBREAKF_CTRL_C | sushisignal );
/* Make sure you turn off your compiler's CTRL-C handling
* if you use CTRL-C as your exit signal.
*/
if( signals & SIGBREAKF_CTRL_C)
{
Done = TRUE;
}
if(signals & sushisignal)
{
/* There's some new info in the sushi buffer.
* Here we will just print it out.
* You could instead copy it elsewhere for fancy display, etc.
*/
bufi = aps->subufi; /* grab where sushi has filled to */
if(bufi > bufli) /* buffer has not wrapped since last */
{
Write(Output(),&buf[bufli],bufi - bufli);
}
else if(bufli > bufi) /* buffer has wrapped since last */
{
/* Write end of buffer info, then new info at start of buffer */
Write(Output(),&buf[bufli],aps->subufsize - bufli);
Write(Output(),buf,bufi);
}
/* Update variable that saves where YOU are up to */
bufli = bufi;
}
#if 0
/* FYI - Other things you can tell Sushi to do */
/* Tell Sushi to write its buffer as file t:sushi.out.
* Sushi writes its buffer in chronological order -
* i.e., if the buffer has wrapped, it writes older end of buffer,
* then writes data from start of buffer to current position.
*/
Signal(aps->sutask, SIGBREAKF_CTRL_F);
/* Tell Sushi to empty (clear) its buffer (i.e. reset its indexes).
* If you do this, you should probably reset your bufli to 0.
*/
Signal(aps->sutask, SIGBREAKF_CTRL_E);
/* Tell Sushi to exit if it can.
* It can not exit if there is an aps->extsigtask.
*/
Signal(aps->sutask, SIGBREAKF_CTRL_C);
#endif
}
bye("",RETURN_OK); /* Will do Sushi and other cleanup */
}
void bye(UBYTE *s, int e)
{
cleanup();
exit(e);
}
void cleanup()
{
/* Required cleanup for external sushi program before exiting ! */
if(GotSushi && (aps != NULL))
{
/* Required Sushi cleanup before you exit !!!! */
Forbid();
aps->extsignum = 0L;
aps->extsignal = 0L;
aps->extsigtask = NULL;
Permit();
}
if(sushisignum != -1) FreeSignal(sushisignum);
}